package com.xian.ucenter.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xian.ucenter.commons.Result;
import com.xian.ucenter.controller.front.PostFrontController;
import com.xian.ucenter.entities.Post;
import com.xian.ucenter.entities.User;
import com.xian.ucenter.entities.vo.PostVo;
import com.xian.ucenter.entities.vo.UserLogin;
import com.xian.ucenter.security.entities.SecurityUser;
import com.xian.ucenter.service.IndexService;
import com.xian.ucenter.service.TagService;
import com.xian.ucenter.service.UserService;
import com.xian.ucenter.utils.ConstantUtil;
import com.xian.ucenter.utils.JwtUtil;
import com.xian.ucenter.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
public class IndexServiceImpl implements IndexService {
    @Autowired
    private UserService userService;
    @Autowired
    private TagService tagService;
    @Autowired
    private PostFrontController postFrontController;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Override
    public Result getIndexInfo() {
        return Result.ok("blogUser",userService.getUserInfo());
    }
    @Override
    public Result login(UserLogin userLogin) {
        Authentication authentication = new UsernamePasswordAuthenticationToken(userLogin.getUsername(),userLogin.getPassword(),new ArrayList<>());
        Authentication authenticate = authenticationManager.authenticate(authentication);
        if (Objects.isNull(authenticate)) {
            return Result.fail("用户名密码错误！");
        }
        SecurityUser loginUser = BeanUtil.copyProperties(authenticate.getPrincipal(), SecurityUser.class);
        User user = BeanUtil.copyProperties(loginUser.getLoginUserInfo(), User.class);
        user.setPassword("");
        String userId = user.getId();
        String userJwtToken = JwtUtil.getUserJwtToken(userId, user.getUsername());
        redisUtil.setEx(ConstantUtil.LOGIN_USER_KEY+userId, JSONUtil.toJsonStr(user),30L, TimeUnit.MINUTES);
        return Result.ok("Authentication",userJwtToken);
    }

    @Override
    public Result logout(HttpServletRequest request) {
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        SecurityUser loginUser = (SecurityUser) authentication.getPrincipal();
        String userId = BeanUtil.copyProperties(loginUser.getUsername(),User.class).getId();
        redisUtil.delete(ConstantUtil.LOGIN_USER_KEY+userId);
        return Result.ok("登出成功！");
    }

    @Override
    public Result getInfo(HttpServletRequest request) {
        String userId = JwtUtil.getIdByJwtToken(request);
        User user = JSONUtil.toBean(redisUtil.get(ConstantUtil.LOGIN_USER_KEY + userId),User.class);
        String token = "";
        if (StringUtils.hasText(user.getId())) {
            token = request.getHeader("Authentication");
        }
        return Result.ok("blogUser",user).data("token",token);
    }

    @Override
    public Result getLastPosts() {
        QueryWrapper<Post> postQuery = new QueryWrapper<Post>().eq("status", 0);
        Page<Post> page = postFrontController.pageList(1, 3, postQuery);
        List<PostVo> list = BeanUtil.copyToList(page.getRecords(), PostVo.class);
        list.forEach(postVo -> {
            postVo.setList(tagService.getTagNamesByPostId(postVo.getId()));
        });
        return Result.ok().data("list",list);
    }
}
